package de.ba.se.roboter.data;

/**
 * Diese Klasse stellt das Datenmodell dar.
 * 
 * @author Sebastian Tönse
 *
 */
public class Robot {
	
	private Orienation orienation;
	
	private int x;
	
	private int y;
	
	private boolean[][] field;
	
	private int stepCount = 0;
	
	private String methods = "";
	
	/**
	 * default c-tor
	 */
	public Robot() {
		this.field = new boolean[9][9];
		this.x = 4;
		this.y = 4;
		this.orienation = Orienation.NORTH;
	}
	
	/**
	 * Konstruktor, für die Initialisierung über die GUI. Die Startposition wird in Abhängigkeit des Feldes ermittelt. Startposition = Breite / 2 &amp; Höhe / 2. 
	 * @param orienation Initiale Blickrichtung
	 * @param field Das Feld, auf dem der {@link Robot} läuft.
	 */
	public Robot(Orienation orienation, boolean[][] field) {
		super();
		this.orienation = orienation;
		this.field = field;
		this.x = field.length / 2;
		this.y = field[0].length / 2;
		
	}

	/**
	 * Gibt die aktuelle Blickrichtung zurück.
	 * @return Die aktuelle Blickrichtung.
	 */
	public Orienation getOrienation() {
		return orienation;
	}

	/**
	 * Setzt die Blickrichtung.
	 * @param orienation Die gewünschte Richtung
	 */
	public void setOrienation(Orienation orienation) {
		this.orienation = orienation;
	}

	/**
	 * Die x-Koordinate im Feld
	 * @return x-Koord
	 */
	public int getX() {
		return x;
	}

	/**
	 * Setzt die x-Koordinate
	 * @param x Die gewünschte x-Koordinate
	 */
	public void setX(int x) {
		this.x = x;
	}

	/**
	 * Die y-Koordinate im Feld
	 * @return y-Koord
	 */
	public int getY() {
		return y;
	}

	/**
	 * Setzt die y-Koordinate
	 * @param y Die gewünschte x-Koordinate
	 */
	public void setY(int y) {
		this.y = y;
	}

	/**
	 * Das Feld, auf dem sich der {@link Robot} bewegt.
	 * @return Das Feld
	 */
	public boolean[][] getField() {
		return field;
	}

	/**
	 * Setzt das Feld.
	 * @param field Feld
	 */
	public void setField(boolean[][] field) {
		this.field = field;
	}
	
	/**
	 * Drehung nach links.
	 */
	public void turnLeft() {
		switch (orienation) {
			case NORTH:
				orienation = Orienation.WEST;
				break;
			case EAST: 
				orienation = Orienation.NORTH;
				break;
			case SOUTH:
				orienation = Orienation.EAST;
				break;
			case WEST: 
				orienation = Orienation.SOUTH;
				break;
		}
	}
	
	/**
	 * Drehung nach rechts.
	 */
	public void turnRight() {
		switch (orienation) {
			case NORTH:
				orienation = Orienation.EAST;
				break;
			case EAST: 
				orienation = Orienation.SOUTH;
				break;
			case SOUTH:
				orienation = Orienation.WEST;
				break;
			case WEST: 
				orienation = Orienation.NORTH;
				break;
		}
	}
	
	/**
	 * Einen Schritt gehen.
	 */
	public void step() {
		switch (orienation) {
			case NORTH:
				y--;
				break;
			case EAST: 
				x++;
				break;
			case SOUTH:
				y++;
				break;
			case WEST: 
				x--;
				break;
		}
	}
	
	/**
	 * Invertiert das aktuelle Feld.
	 */
	public void invert() {
		field[x][y] = !field[x][y];
	}
	
	/**
	 * Die Regeln, nach denen der {@link Robot} auf dem Feld laufen soll.
	 * @return <code>true</code>, wenn der {@link Robot} am Rand des Feldes ist, sonst <code>false</code>
	 */
	public boolean turn() {
		if (x >= 0 && x < field.length && y >= 0 && y < field[0].length) {
			stepCount++;
			if(field[x][y]) {
				turnLeft();
				invert();
				step();
				methods = "links -> invertiere -> Schritt";
			} else {
				turnRight();
				invert();
				step();
				methods = "rechts -> invertiere -> Schritt";
			}
			return true;
		}
		return false;
		//System.out.println(showField());
	}
	
	/**
	 * Aktuelle Schrittanzahl.
	 * @return Aktuelle Schrittanzahl.
	 */
	public int getStepCount() {
		return stepCount;
	}
	
	/**
	 * Aktueller Schritt.
	 * @return Aktueller Schritt.
	 */
	public String getMethods() {
		return methods;
	}

	/**
	 * Für die Konsolenausgabe.
	 * @return Konsolenausgabe.
	 */
	private String showField() {
		final StringBuilder builder = new StringBuilder();
		for (int i = 0; i < field.length; i++) {
			for (int j = 0; j < field[0].length; j++) {
				builder.append(field[j][i]? 1 : 0);
			}
			builder.append(System.lineSeparator());
 		}
		return builder.toString();
	}
}
